/*
 * @Author: huangxuzhong
 * @Date: 2021-11-08 10:04:19
 * @LastEditTime: 2023-03-10
 * @LastEditors: Tommy Chen
 * @Description: 设备处理工具类
 * @FilePath: /macc.admin.vue/src/utils/deviceTools.js
 */

import { requestHttp, maccApi } from './index';
import { i18nRender } from '@/locales';
/**
 * @description: 获取设备面板布局
 * @param {*} sn   设备序列号
 * @param {*} productClass 产品型号
 * @param {*} store vuex缓存对象
 * @param {*} onlyPorts 面板布局只包含ports数据,兼容网关
 * @return {*}
 */
const getDevicePanelLayout = async function (
  sn,
  productClass,
  store,
  onlyPorts = false
) {
  const multiPanelClass = store.state.devices.multiPanelClass;
  const deviceLayout = store.state.devices.deviceLayout;
  console.log('==========缓存数据', multiPanelClass, deviceLayout);
  let slots = [];
  //先判断是否是多面板交换机
  if (multiPanelClass.indexOf(productClass) > -1) {
    slots = await getMultiPanelLayout(sn, productClass);
  } else {
    const slotList = await getSwitchSlotList(sn);
    for (let i = 0; i < slotList.length; i++) {
      const slot = slotList[i];
      if (deviceLayout[slot.configModule]) {
        if (onlyPorts) {
          slots.push({
            ports: deviceLayout[slot.configModule],
          });
        } else {
          slots.push({
            devId: slot.devId,
            slotId: slot.slotId,
            ports: deviceLayout[slot.configModule],
            productClass: slot.configModule,
          });
        }
      } else {
        if (slot.configModule) {
          const ports = await getSingDevicePanelLayout(slot.configModule);
          deviceLayout[slot.configModule] = ports;

          let product = {};
          product[slot.configModule] = ports;
          store.dispatch('devices/setDeviceLayout', product);
          if (onlyPorts) {
            slots.push({
              ports: ports,
            });
          } else {
            slots.push({
              devId: slot.devId,
              slotId: slot.slotId,
              ports: ports,
              productClass: slot.configModule,
            });
          }
        }
      }
    }
  }
  return slots;
};

/**
 * 获取NBS系列多面板布局
 * @param {*} sn
 * @returns
 */
const getMultiPanelLayout = async function (sn) {
  try {
    const results = await requestHttp({
      api: `${maccApi.DEVICE_SWTICHNBS_MUIPANELLAYOUT_GET_API.replace(
        '{sn}',
        sn
      )}`,
      method: 'GET',
    });
    if (results && results.code == 0) {
      const switchSlot = formatVsuDeviceLayout(results);
      return switchSlot;
    } else {
      return [];
    }
  } catch (e) {
    console.log(e);
    return [];
  }
};
/**
 * 格式化设备热备信息
 * @param {*} data
 * @returns
 */
const formatVsuDeviceLayout = function (data) {
  if (data.mswVsuDeviceInfoList) {
    const vsuInfo = data.mswVsuDeviceInfoList;
    const switchSlot = data.switchSlot || [];
    return switchSlot.map((item) => {
      const deviceVsuInfo = vsuInfo.find((device) => {
        return device.switchId == item.devId;
      });
      return { ...item, deviceVsuInfo };
    });
  } else {
    return data.switchSlot || [];
  }
};

/**
 * 获取普通交换机卡槽列表
 * @param {*} sn
 * @returns
 */
const getSwitchSlotList = async function (sn) {
  try {
    const results = await requestHttp({
      api: `${maccApi.DEVICE_SWTICH_SLOTS_GET_API.replace('{sn}', sn)}`,
      method: 'GET',
    });
    if (results && results.code == 0) {
      return results.data || [];
    } else {
      return [];
    }
  } catch (e) {
    console.log(e);
    return [];
  }
};

/**
 * 触发交换机端口数据更新
 * @param {*} sn
 * @returns
 */
const triggerSwitchPortInfoUpdata = async function (sn) {
  try {
    const api = maccApi.SWITCH_POTRSLISTTRIGGER_POST_API.replace('{sn}', sn);
    const { code } = await requestHttp({ api, method: 'POST', params: {} });
    if (code == 0) {
      return true;
    } else {
      return false;
    }
  } catch (e) {
    console.error(e);
    return false;
  }
};

/**
 * 获取单面板端口布局
 * @param {*} productClass
 */
const getSingDevicePanelLayout = async function (productClass) {
  try {
    const results = await requestHttp({
      api: `${maccApi.DEVICE_PANELLAYOUT_GET_API.replace(
        '{productClass}',
        productClass
      )}`,
      method: 'GET',
    });
    if (results && results.code == 0) {
      return results.ports || [];
    } else {
      return [];
    }
  } catch (e) {
    console.log(e);
    return [];
  }
};

/**
 * 获取网关设备外网口的配置信息
 * @param {*}
 */
const getDeviceGatewayPortInfo = async function (portList, osType) {
  let providerserver = {
    cnc: i18nRender('wanMultiOut.unicom'),
    cnii: i18nRender('wanMultiOut.telecom'),
    cmcc: i18nRender('wanMultiOut.mobile'),
    cernet: i18nRender('wanMultiOut.education'),
    beijingteletron: i18nRender('wanMultiOut.telecomTong'),
  };
  let wanList = [];
  for (let key in portList) {
    let item = portList[key].portData;
    if (item.ipType != 'none' && item.type == 'WAN') {
      let name = '';
      if (item.pannelName) {
        name = item.pannelName;
        if (item.pannelName.indexOf('/') != -1) {
          name = item.pannelName.split('/')[1];
        }
        name = `${name}(${item.alias})`;
      } else {
        name = item.alias;
      }

      let wanPort = {
        wanName: `${name}`,
        port: item.port,
        ispDesc: providerserver[item.isp] || '',
        isp: 'other',
      };
      if (
        item.isp &&
        providerserver[item.isp] &&
        (item.isp == 'cnc' || item.isp == 'cnii' || item.isp == 'cmcc')
      ) {
        wanPort.isp = item.isp;
      }
      if (item.ipType == 'static') {
        if (osType == 'rgos') {
          if (!item.defaultRouteEnable) {
            wanPort.ispDesc = i18nRender('common.privateLine');
            wanPort.isp = 'line';
          }
        } else {
          if (item.isSpecialLine) {
            wanPort.ispDesc = i18nRender('common.privateLine');
            wanPort.isp = 'line';
          }
        }
      }
      wanList.push(wanPort);
    }
  }
  return wanList;
};

/**
 * 触发网关接口数据更新
 * @param {*} sn
 * @returns
 */
const triggerEgPortInfoUpdata = async function (sn) {
  let params = {
    api: `${maccApi.DEVICE_EGW_INFT_TRIGGER_API.replace('{sn}', sn)}`,
    method: 'POST',
  };
  if (process.env.VUE_APP_MACC_ENV == 'INTL') {
    params.body = {
      aaa: '111',
    };
  }
  const ret = await requestHttp(params);
  return ret;
};

const triggerRefreshEg = async function (sn) {
  const ret = await triggerEgPortInfoUpdata(sn);
  if (ret.code == 0) {
    this.$store.dispatch('SpeedMultiOut/getGatewayIntfInfo', {
      sn: sn,
    });
    //注册网关更新事件
    let timeOut = setTimeout(() => {
      this.$store.dispatch('SpeedMultiOut/getGatewayIntfInfo', {
        sn: sn,
      });
    }, 30000);
    console.log('触发网关数据更新', this, this.$iframeMsg, this.$store);
    this.$iframeMsg('REGISTER_COMTED', {
      eventName: 'GATEWAY_INTF_INFO_STATUS_CHANGE',
      comtedCallback: () => {
        timeOut && clearTimeout(timeOut);
        this.$store.dispatch('SpeedMultiOut/getGatewayIntfInfo', {
          sn: sn,
        });
      },
    });
  }
};

const triggerEapPortUpdata = async function (sn) {
  const api = maccApi.DEVICE_EAP_TRIGGERPORTINFOUPTATA_GET_API;
  const res = await requestHttp({ api, method: 'GET', querys: { sn: sn } });
  return res;
};

/**
 * 检查NBS交换机是否离线状态接口不配置
 * @param {*} onlineStatus 设备在线状态
 * @param {*} productClass 设备型号
 * @param {*} store vuex缓存
 * @returns
 */
const checkMutilPanelPortsDisabled = function (
  onlineStatus,
  productClass,
  store
) {
  const multiPanelClass = store.state.devices.multiPanelClass;
  if (onlineStatus != 'ON' && multiPanelClass.indexOf(productClass) > -1) {
    return true;
  } else {
    return false;
  }
};

/**
 * 格式化端口名称
 * @param {Array} alias
 * @returns
 */
const formatterAlias = function (alias) {
  alias = Array.from(new Set(alias));
  let aliasArray = alias.concat([]);

  //别名排序
  aliasArray.sort(function (a, b) {
    let as = (a.match(/\d+$/g) && a.match(/\d+$/g)[0]) || 0;
    let bs = (b.match(/\d+$/g) && b.match(/\d+$/g)[0]) || 0;
    return as - bs;
  });
  //定义前缀数组
  var aliasPrefix = {};
  for (let i = 0; i < aliasArray.length; i++) {
    let aliasItem = aliasArray[i];
    let num = (aliasItem.match(/\d+$/g) && aliasItem.match(/\d+$/g)[0]) || '';
    let prefix = aliasItem.replace(/\d+$/, '');
    if (aliasPrefix[prefix]) {
      if (num) {
        aliasPrefix[prefix].push(parseInt(num));
      }
    } else {
      aliasPrefix[prefix] = [];
      if (num) {
        aliasPrefix[prefix].push(parseInt(num));
      }
    }
  }

  console.log('前缀排序对象', aliasPrefix);

  let str = '';
  for (let name in aliasPrefix) {
    let aliasString = aliasFormat(name, aliasPrefix[name]);
    str += aliasString + ',';
  }

  return str.slice(0, str.length - 1);
};

/**
 * 同前缀别名格式化
 * @param {*} prefix
 * @param {*} numArray
 * @returns
 */
const aliasFormat = function (prefix, numArray) {
  let newList = '';
  let max = numArray[0],
    min = numArray[0];
  if (numArray.length > 0) {
    for (let i = 0; i < numArray.length; i++) {
      let j = i + 1;
      if (j >= numArray.length) j = i; //注意：因为j=i+1,所以j会出现超出数组下标范围的情况
      //先比较第一个和第二个，如果连续，再比较第二个和第三个...直到出现不连续时就输出缩写1-3，再进行下面数字的比较
      if (numArray[i] == numArray[j] - 1) {
        //如果连续，就先暂时把Arr[j]赋值给-右侧的数字
        max = numArray[j];
      } else {
        if (i == numArray.length - 1) {
          //如果没有这个判断最后会输出newlist="1-3,7-7,10-15,"会多一个‘，’
          if (min == max) {
            newList += prefix + min;
          } else {
            newList += prefix + min + '-' + max;
          }
        } else {
          if (min == max) {
            newList += prefix + min + ',';
          } else {
            newList += prefix + min + '-' + max + ',';
          }
        }
        //此时将min和max都赋值为7
        if (j < numArray.length) {
          min = numArray[j];
          max = numArray[j];
        }
      }
    }
  } else {
    newList = prefix;
  }

  return newList;
};

//图标映射关系
const iconTypeMap = {
  over: {
    SWITCH: 'device-switch',
    OTHER: 'device-other',
    PRINTER: 'device-printer',
    SERVER: 'device-server',
    PC: 'device-computer',
    NVR: 'device-nvr',
    CAMERA: 'device-camera',
    BRIDGE: 'device-bridge',
    AP: 'device-ap',
    AC: 'device-ac',
    EXIT_ROUTER: 'device-router',
    videointercom: 'device-visual',
    union: 'port-union',
  },
  status: {
    poe: 'port-POE',
    poeEabnormal: 'port-POEabnormal',
    block: 'port-block',
    hpoe: 'port-HPOE',
    loop: 'port-ring',
    fs: 'port-FS',
  },
};

/**
 * 设备绿色端口速率
 */
const greenSpeed = [
  '1000M',
  '10000M',
  '2500M',
  '5000M',
  '10G',
  '20G',
  '25G',
  '40G',
  '100G',
];

/**
 * 获取交换机order
 * @param {*} itemgreenSpeed
 * @returns
 */
const getSwitchOrder = function (item) {
  return item.orderAlias || item.order;
};

/**
 * 格式化聚合口
 * @param {*} portData
 */
const formatterSwitchAgObj = function (portData) {
  const agobj = {};
  if (
    Object.prototype.toString.call(portData) == '[object Array]' &&
    portData.length > 0
  ) {
    for (let i = 0; i < portData.length; i++) {
      if (portData[i].portGroupId > 0) {
        if (agobj[portData[i].portGroupId]) {
          agobj[portData[i].portGroupId].push(portData[i].alias);
        } else {
          agobj[portData[i].portGroupId] = [];
          agobj[portData[i].portGroupId].push(portData[i].alias);
        }
      }
    }
  }
  return agobj;
};

const switchSpeedMap = {
  Fa: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '10M', value: '10M' },
    { desc: '100M', value: '100M' },
  ],
  Gi: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '10M', value: '10M' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
  ],
  Mt: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
    { desc: '2500M', value: '2500M' },
  ],
  Te: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
    { desc: '2500M', value: '2500M' },
    { desc: '5000M', value: '5000M' },
    { desc: '10G', value: '10G' },
  ],
  Tw: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '20G', value: '20G' },
  ],
  Hu: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '40G', value: '40G' },
    { desc: '100G', value: '100G' },
  ],
  TF: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '10M', value: '10M' },
    { desc: '1000M', value: '1000M' },
    { desc: '10G', value: '10G' },
    { desc: '25G', value: '25G' },
  ],
  Fo: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '40G', value: '40G' },
  ],
  //全光开始
  Gt: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '10M', value: '10M' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
  ],
  Fi: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
    { desc: '2500M', value: '2500M' },
    { desc: '5000M', value: '5000M' },
  ],
  Sfp: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '100M', value: '100M' },
    { desc: '1000M', value: '1000M' },
  ],
  Xs: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '1000M', value: '1000M' },
    { desc: '10G', value: '10G' },
  ],
  Cq: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '40G', value: '40G' },
    { desc: '100G', value: '100G' },
  ],
  Vs: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '1000M', value: '1000M' },
    { desc: '10G', value: '10G' },
    { desc: '25G', value: '25G' },
  ],
  Xt: [
    { desc: i18nRender('deviceDetail.negotiation'), value: 'Auto' },
    { desc: '1000M', value: '1000M' },
    { desc: '2500M', value: '2500M' },
    { desc: '5000M', value: '5000M' },
    { desc: '10G', value: '10G' },
  ],
};

/**
 * 获取面板端口图标
 * @param {*} mediumType
 * @returns
 */
const getDevicePanelPortIcon = function (mediumType = '', agfix = '') {
  let icon = '';
  const me = mediumType ?? '';
  //考虑到某些列表也使用这个来判断端口的图标，大小写规则可能和端口数据不一样，故全部转成小写
  const mediumTypeLow = me.toLocaleLowerCase();
  switch (mediumTypeLow) {
    case 'fiber': {
      icon = 'ic-port-light';
      break;
    }
    case 'phone': {
      icon = 'ic-port-phone';
      break;
    }
    case 'fiberbranch': {
      icon = 'ic-port-SC';
      break;
    }
    default: {
      icon = 'ic-port-electric';
      break;
    }
  }
  return icon + `${agfix ? '-' + agfix : ''}`;
};

/**
 * 判断当前口是否生效
 * @param {*} portMediumType
 * @param {*} localMediumType
 */
const checkMultiplexing = function (portMediumType, localMediumType) {
  //判断接口数据是否存在MediumType
  if (portMediumType) {
    //如果接口数据是分光模式或者本地是sc光口，那么就不是光电复用
    if (
      //localMediumType.toLocaleLowerCase() == 'Fiber'.toLocaleLowerCase() ||
      portMediumType.toLocaleLowerCase() == 'fiberBranch'.toLocaleLowerCase()
    ) {
      return true;
    }
    return (
      portMediumType.toLocaleLowerCase() == localMediumType.toLocaleLowerCase()
    );
  } else {
    return true;
  }
};

/**
 * 交换机配置是否相等
 * @param {*} arr
 * @returns
 */
const isSame = function (arr) {
  if (arr.length == 0) {
    //有可能都没有poe供电
    return true;
  }
  let isSame = true;
  const first = arr[0];
  for (let i = 0; i < arr.length; i++) {
    if (first != arr[i]) {
      isSame = false;
    }
  }
  if (isSame) {
    if (typeof arr[0] == 'undefined') {
      //需要取第一个看看是不是undefined,有可能全部都是undefined
      return false;
    }
  }
  return isSame;
};

const CDIR2netmask = function (bitCount) {
  const mask = [];
  for (let i = 0; i < 4; i++) {
    const n = Math.min(bitCount, 8);
    mask.push(256 - Math.pow(2, 8 - n));
    bitCount -= n;
  }
  return mask.join('.');
};

const netmask2CIDR = (netmask) =>
  netmask
    .split('.')
    .map(Number)
    .map((part) => (part >>> 0).toString(2))
    .join('')
    .split('1').length - 1;

export {
  getDevicePanelLayout,
  checkMutilPanelPortsDisabled,
  formatterAlias,
  getSwitchOrder,
  getDeviceGatewayPortInfo,
  triggerRefreshEg,
  formatterSwitchAgObj,
  iconTypeMap,
  greenSpeed,
  switchSpeedMap,
  isSame,
  CDIR2netmask,
  netmask2CIDR,
  triggerSwitchPortInfoUpdata,
  triggerEgPortInfoUpdata,
  getDevicePanelPortIcon,
  checkMultiplexing,
  triggerEapPortUpdata,
};
